package com.gitee.feizns.bean;

import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * 属性.
 * @author feizns
 * @since 2019/6/5
 */
public interface Property<T> extends AnnotatedElement {

    /**
     * 获取属性值
     * @return value
     */
    default T val() {
        return null;
    }

    /**
     * 获取属性值
     * @return value
     */
    default <R> R val(Class<R> targetType) {
        return null;
    }

    /**
     * 为属性赋值
     * @param newVal
     * @return oldVal
     */
    default T getAndSet(T newVal) {
        return val();
    }

    /**
     * 设置属性
     * @param newVal
     * @return
     */
    default Property<T> set(Object newVal) {
        return this;
    }

    /**
     * 获取属性
     * @return
     */
    default Property<Object> get(String name) {
        return of(val(), name);
    }

    /**
     * 获取属性
     * @param name
     * @param targetType
     * @param <P>
     * @return
     */
    default <P> Property<P> get(String name, Class<P> targetType) {
        return of(val(), name, targetType);
    }

    /**
     * 属性名
     * @return
     */
    default String name() {
        return null;
    }

    /**
     * 是否可读
     * @return
     */
    default boolean isReadable() {
        return false;
    }

    /**
     * 是否可写
     * @return
     */
    default boolean isWritable() {
        return false;
    }

    /**
     * 获取属性所属的对象
     * @return
     */
    default Object getTarget() {
        return null;
    }

    /**
     * 获取字段
     * @return
     */
    default Field getField() {
        return null;
    }

    /**
     * 读方法
     * @return
     */
    default Method readMethod() {
        return null;
    }

    /**
     * 写方法
     * @return
     */
    default Method writeMethod() {
        return null;
    }

    @Override
    default <T extends Annotation> T getAnnotation(Class<T> annotationClass) {
        return null;
    }

    @Override
    default Annotation[] getAnnotations() {
        return new Annotation[0];
    }

    @Override
    default Annotation[] getDeclaredAnnotations() {
        return new Annotation[0];
    }

    /**
     * 构建
     * @param target
     * @param name
     * @param <D>
     * @return
     */
    static <D> Property<D> of(Object target, String name) {
        return new DefaultPropertyImpl<>(target, name);
    }

    /**
     * 构建
     * @param target
     * @param name
     * @param <D>
     * @return
     */
    static <D> Property<D> of(Object target, String name, Class<D> targetType) {
        return new DefaultPropertyImpl<>(target, name);
    }

}

